/**
  ETFAna project, Anyang Normal University && IMP-CAS
  \class ETFTimer1
  \brief a single-ended plastic scintillator
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2021-10-30
  \date 2021-12-06 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date         <th>Author      <th>Description                   </tr>
  <tr>  <td>2021-10-30   <td>Asia Sun    <td>file created                  </tr>
  </table>

  \copyright Copyright (c) 2021-2024 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#include <cstring>
#include <TClonesArray.h>
#include "ETFTimer1.h"
#include "ETFDetectorManager.h"
#include "ETFPlaHit.h"
#include "ETFMath.h"
#include "ETFMsg.h"
#include "ETFRawChannel.h"
#include "ETFParaManager.h"

ETFTimer1::ETFTimer1(const char *name, double length) : ETFTimer(name, length){
  const int chId0 = fChIdConfig.as<int>();
  if(chId0 >= 0){
    SetChMap(chId0, fDetId); // UV
    SetChMap(chId0+1, fDetId + (1<<8)); // UH
  } // end if
  if(fQChIdConfig.good()) SetChMap(fQChIdConfig[0].as<int>(), fDetId + (4<<8)); // UQ
} // end ctor

// return the fired status of Tstop
int ETFTimer1::GetFiredStatus() const{
  if(!fHits->GetEntriesFast()) return -1;
  return dynamic_cast<ETFPlaHit *>((*fHits)[0])->GetFiredStatus();
} // end member function GetFiredStatus

// add time ch
void ETFTimer1::Assign(const ETFRawChannel *ch, unsigned uid){
  const int vh = uid>>8 & 0x7;
  if(1 == vh) return; // ommit (SFE16) TOT channel

  AddHit(ch, vh);
} // end member function Assign

void ETFTimer1::AddHit(const ETFRawChannel *ch, int vh){
  ETFPlaHit *hit = nullptr;
  for(auto p : *fHits){
    ETFPlaHit *h = static_cast<ETFPlaHit *>(p);
    if(h->GetStripId() == 0){ // old strip
      hit = h; continue;
    } // end if
  } // end for
  if(!hit && ch->IsT()){ // create a new strip: Q ch does not trigger this
    hit = static_cast<ETFPlaHit *>(fHits->ConstructedAt(fHits->GetEntriesFast()));
    hit->Initialize();
    hit->SetStripId(0);
    hit->SetLength(fLength);
    hit->SetDelay(fDelay);
    hit->SetName(GetName());
    // double pos[3]{}; hit->SetPosition(pos); // no need for position currently
    // TransformToLabRef(hit);
    fIsFired = true;
  } // end if
  if(ch->IsT()) hit->SetTChannel(ch, vh);
  else hit->SetQChannel(ch, vh);
} // end member function AddHit

// get the timing signal of Tstart
double ETFTimer1::GetTime() const{
  if(!fHits->GetEntriesFast()) ETFMsg::Error("ETFTimer1", "GetTime: No hits in Tstart");
  return dynamic_cast<ETFPlaHit *>(fHits->At(0))->GetTimeU();
} // end member function GetTime
